// reverse a slice of ints in place.
package main

import (
	"fmt"
	"unicode"
	"unicode/utf8"
)

func main() {
	a := []int{0, 1, 2, 3, 4, 5}
	reverse(a[:2])
	reverse(a[2:])
	reverse(a[:])
	fmt.Println(a)

	b := [6]int{0, 1, 2, 3, 4, 5}
	reverse1(&b)
	fmt.Println(b)
	c := []int{0, 1, 2, 3, 4, 5}
	rotate(c, 2)
	fmt.Println(c)
	d := []int{0, 1, 2, 3, 4, 5}
	d = remove(d, 1)
	fmt.Println(d)
	strings := []string{"a", "b", "c", "c", "d", "e", "f"}
	fmt.Println(quchong(strings))
	runes := []rune("a b c c d e 	f 中		国")
	runes = replaceSpace(runes)

	fmt.Printf("%v\n", string(runes))
	bytes := []byte("abc中国")
	reverse2(bytes)
	fmt.Printf("%v\n", string(bytes))
	bytes1 := []byte("中国cba")
	reverse2(bytes1)
	fmt.Printf("%v\n", string(bytes1))
}
func remove(s []int, i int) []int {
	s[i] = s[len(s)-1]
	return s[:len(s)-1]
}
func reverse(s []int) {
	fmt.Println(len(s), cap(s))
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}
}

// 练习 4.3: 重写reverse函数，使用数组指针代替slice。
func reverse1(s *[6]int) {
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}
}

// 练习 4.4: 编写一个rotate函数，通过一次循环完成旋转。
func rotate(s []int, n int) {
	l := len(s)
	n = n % l
	if n == 0 {
		return
	}
	for i := 0; i < n; i++ {
		tmp := s[0]
		copy(s[0:], s[1:])
		s[l-1] = tmp
	}
}

// 练习 4.5: 写一个函数在原地完成消除[]string中相邻重复的字符串的操作。
func quchong(s []string) []string {
	l := len(s)
	for i := 0; i < len(s)-2; i++ {
		if s[i] == s[i+1] {
			copy(s[i:], s[i+1:])
			l--
		}
	}
	return s[:l]
}

// 练习 4.6: 编写一个函数，原地将一个UTF-8编码的[]byte类型的slice中相邻的空格(参考 unicode.IsSpace)替换成一个空格返回
func replaceSpace(runes []rune) []rune {
	l := len(runes)
	for i := 1; i < len(runes)-1; i++ {
		if unicode.IsSpace(runes[i-1]) && unicode.IsSpace(runes[i]) {
			l--
			copy(runes[i-1:], runes[i:])

		}
		if unicode.IsSpace(runes[i-1]) {
			runes[i-1] = rune(' ')
		}
	}
	return runes[:l]
}

// 练习 4.7: 修改reverse函数用于原地反转UTF-8编码的[]byte。是否可以不用分配额外的内 存?
func reverse2(s []byte) {
	len1 := len(s)            // 字节长度
	len2 := utf8.RuneCount(s) //字符长度
	q := 0                    // 前面字节指针
	h := len1                 // 后面字节指针

	// fmt.Println(s)
	for i, j := 0, len2-1; i < j; i, j = i+1, j-1 {
		m := 1
		if byte(s[q]&192) == 192 { //11000000
			m = 2
		}
		if byte(s[q]&224) == 224 { //11100000
			m = 3
		}
		if byte(s[q]&240) == 240 { //11110000
			m = 4
		}
		n := 1
		for byte(s[h-n]) < 192 && byte(s[h-n]) > 127 { // 后面数字符开始的字节
			// fmt.Println(byte(s[h-n]))
			n++
		}
		// fmt.Println(m, n, q, h, i, j, s[h-n])
		tmpM := make([]byte, m)
		tmpN := make([]byte, n)

		copy(tmpM, s[q:q+m])
		copy(tmpN, s[h-n:h])
		copy(s[q+n:h-m], s[q+m:h-n])
		copy(s[q:q+n], tmpN)
		copy(s[h-m:h], tmpM)
		q += n
		h -= m
	}
}
